﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Drawing;
using System.IO;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace ByteView
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            using (OpenFileDialog dialog = new OpenFileDialog())
            {
                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    Image image = null;
                    try
                    {
                        image = ConvertFileToImage(dialog.FileName);
                        var path = Path.Combine(Path.GetTempPath(), DateTime.Now.Ticks.ToString() + ".bmp");

                        using (var s = new FileStream(path, FileMode.Create, FileAccess.Write))
                        {
                            s.SetLength(image.Width * image.Height);
                            image.Save(s, ImageFormat.Bmp);
                        }
                                                

                        var p = System.Diagnostics.Process.Start(path);
                        p.WaitForExit();

                        if (MessageBox.Show("Delete temporary file " + path, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                            File.Delete(path);
                    }
                    finally
                    {
                        if (null != image)
                            image.Dispose();
                    }
                }
            }            
        }

        static Image ConvertFileToImage(string fileName)
        {
            using (var s = new FileStream(fileName, FileMode.Open, FileAccess.Read))
            {
                int sideLength = (int)Math.Ceiling(Math.Sqrt(s.Length));

                Bitmap result = new Bitmap(sideLength, sideLength, PixelFormat.Format8bppIndexed);

                BitmapData data = result.LockBits(new Rectangle(0, 0, result.Width, result.Height),ImageLockMode.ReadWrite,PixelFormat.Format8bppIndexed);

                long ptr = data.Scan0.ToInt64();
                
                byte[] array = new byte[sideLength];

                for (int i = 0; i < sideLength; i++)
                {
                    int bytesRead = s.Read(array, 0, array.Length);
                    
                    if(0 == bytesRead) break;

                    Marshal.Copy(array, 0,  new IntPtr(ptr+i * data.Stride), bytesRead);
                }
        
                result.UnlockBits(data);

                return result;
            }
        }
    }
}
